/*
	Librairie structure et include clientTasRepartie
	Soit on renvoie le souhait dans le message concerné
	Soit on renvoie 0 ou -1 en cas d'impossibilité ( Creer des message explicite ? )

*/

/* Structure concernant la donnee elle meme */
typedef struct _client
{
	int socketID;
	int wishes;
}client;

typedef struct _listElementClient{
	client* client;
	struct _listElementClient *next;
}listElementClient;

typedef struct _listClient
{
	listElementClient *listElementClient;
	int size;
}listClient;

typedef struct _descriptorListClientConnecteElement
{
	pthread_t nbThread;
	int socketID;
}descriptorListClientConnecteElement;

typedef struct _listClientConnecteElement
{
	descriptorListClientConnecteElement* descriptor;
	struct _listClientConnecteElement* next;
}listClientConnecteElement;

typedef struct _listClientConnecte
{
	int size;
	listClientConnecteElement* listClientConnecteElement;
	pthread_mutex_t lockListClient;
}listClientConnecte;

typedef struct _dataDescriptor
{
	char* nameData;
	unsigned int sizeData;
	void* emplacementData; /*offset*/
	listClient* listAttente;
	pthread_mutex_t lockData;
}dataDescriptor;

typedef struct _dataServerElement
{
	dataDescriptor* data;
	struct _dataServerElement* next;
}dataServerElement;

typedef struct _dataServerList{
	dataServerElement* data;
	int size;
	pthread_mutex_t lockDataList;
}dataServerList;


typedef struct _descriptorFreeSpace{
	void* debutEspace;
	void* finEspace;
	int taille;
}descriptorFreeSpace;


typedef struct _freeSpaceListElement
{
	descriptorFreeSpace* dfs;
	struct _freeSpaceListElement* next;
}freeSpaceListElement;

typedef struct _freeSpaceList{
	freeSpaceListElement* first;
	int size;
	pthread_mutex_t lockFreeList;
}freeSpaceList;

typedef struct _server{
	dataServerList* donneeServer;
	void* debutTas;
	int tailleTas;
	freeSpaceList* espaceLibre;
	listClientConnecte* listClientConnecte;
	pthread_mutex_t lockServer;
}server;

/* Fin des structure concernant la donnee elle meme */

/* Fonction de gestion des structure local */

/* Creation des structures */

void insertDataDecriptorInServerData(dataDescriptor* dd);

void optimiseEspaceLibre();

void removeFreeSpaceListElement(freeSpaceListElement* fsle);

void addFreeSpaceListElement(freeSpaceListElement* fsle);

listClient*	newListClient();

server* newServer();

dataServerList* newDataServerList();

dataServerElement* newDataServerElement();

listElementClient* newListElementClient();

listClientConnecte* newListClientConnecte();

descriptorListClientConnecteElement* addDescriptorListClientConnecteElement(int socketID, pthread_t nbThread);

listClientConnecteElement* newListClientConnecteElement();

listClientConnecteElement* addListClientConnecteElement(descriptorListClientConnecteElement* dlcce);

descriptorListClientConnecteElement* newDescriptorListClientConnecteElement();

server* initServeur(int tailleTas);

dataDescriptor* newDataDescriptor();

listClient* createListClient();

client* newClient();

client* createClient(int socketID, int wishes);

descriptorFreeSpace* newDescriptorFreeSpace();

descriptorFreeSpace* addDescriptorFreeSpace(void* debutEspace, void* finEspace, int taille);
freeSpaceListElement* newFreeSpaceListElement();

freeSpaceList* newFreeSpaceList();

void* findFreeSpaceWithSize(int size);

/* Fin des create */

/* Debut des find */

dataDescriptor* findDataDescriptor(char* nomVariable);

client* findNextToWork(char* nomVariable);

/* Fin des find */

/* Debut des deletes */

void deleteDataDescriptor(char* nomVariablel);

void deleteClientFromList(listElementClient *list);

void deleteClientDisconnected(client client);

/* Fin des deletes */

/* Debut des updates */

int updateDataDescriptor(char* nameData, void* contentData,  unsigned int sizeNewData);

void addClientListAttente(listClient* list, client* client);

/* Se charge d'enregistrer les donnees d'un dataDescriptor et le retourne complet */
dataDescriptor* addDataDescriptor(	char* nameData, int sizeData, void* contentData);

/* Fin des updates */

/* Fin des fonctions de gestion des structure local */

/* Signatures fonctions message */

int affiche_adresse_socket (int sock);

void* thread_gestion_client(void* arg);

int serveur_tcp();

void addListClientConnecteElementToList(listClientConnecteElement* lcce);

listClientConnecteElement* newListClientConnecteElement();